package com.second.first;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttDefaultFilePersistence;
import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttTopic;


import android.app.ListActivity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.Settings.Secure;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class ListMsgActivity extends ListActivity {

	private String clientId;
	private MqttConnectOptions conOpt;
	private MqttClient client;

	final static String broker = "tcp://test.mosquitto.org:1883";

	private NotificationManager mNotificationManager;

	List<String> messages = new ArrayList<String>();
	Queue<Integer> myQ=new LinkedList<Integer>();
	
	ArrayAdapter<String> adapter;
	
	SharedPreferences prefs;
	SharedPreferences.Editor editor;
	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		Log.d("MQTT", "onCreate");
		
		prefs = PreferenceManager.getDefaultSharedPreferences(this);
		editor = prefs.edit();
		
		connect2MB();

		mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

		adapter = new ArrayAdapter<String>(this, R.layout.list_msg,
				R.id.list4topic, messages);
		setListAdapter(adapter);

		ListView listView = getListView();
		listView.setTextFilterEnabled(true);

		clientId = Secure.getString(this.getContentResolver(),
				Secure.ANDROID_ID);

		listView.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				// When clicked, show a toast with the TextView text
				Toast.makeText(getApplicationContext(),
						((TextView) view).getText(), Toast.LENGTH_SHORT).show();
			}
		});

	}
	
	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		super.onStart();
		Log.d("MQTT", "onStart");

	}



	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		Log.d("MQTT", "onResume");
		String csvList = prefs.getString("myList", "");
		messages.clear();
		if (!csvList.isEmpty())
		{
			String[] items = csvList.split("¤");
			for(int i=0; i < items.length; i++){
				Log.d("MQTT", items[i]);
				messages.add(items[i]);								
			}			
			adapter.notifyDataSetChanged();
		}
		
	}
	
	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		Log.d("MQTT", "onPause");

		
	}

	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		super.onStop();

	}
	
	@Override
	protected void onRestart() {
		// TODO Auto-generated method stub
		super.onRestart();
		Log.d("MQTT", "onRestart");

	}





	private boolean connect2MB() {
		try {

			String tmpDir = System.getProperty("java.io.tmpdir");
			MqttDefaultFilePersistence dataStore = new MqttDefaultFilePersistence(
					tmpDir);
			// Construct the object that contains connection parameters
			// such as cleansession and LWAT
			conOpt = new MqttConnectOptions();
			conOpt.setCleanSession(false);

			// Construct the MqttClient instance
			client = new MqttClient(broker, MqttClient.generateClientId(), null);

			client.setCallback(new MessageHandler());

			client.connect();
			String topics[] = { "cjtest/#" };
			int qos[] = { 0 };
			client.subscribe("cjtest/#", 0);
			return true;
		} catch (MqttException e) {
			e.printStackTrace();
			return false;
		}
	}

	private void showNotification(String topic, String mqttMsg) {

		// Construct content tile of the notification
		CharSequence contentTitle = topic;

		// Construct content text of the notification
		CharSequence contentText = mqttMsg;

		// Construct scrolling text of the notification
		CharSequence scrollingText = "You have 1 new info1k message";

		// Constructs a Notification object with icon, scrolling text and
		// timestamp
		Notification notification = new Notification(R.drawable.ic_launcher,
				scrollingText, System.currentTimeMillis());

		notification.flags |= Notification.FLAG_AUTO_CANCEL;

		// The PendingIntent to launch specific activity if the user selects
		// this notification
		PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
				new Intent(this, ListMsgActivity.class),
				Intent.FLAG_ACTIVITY_CLEAR_TOP);

		// Set the info for the views that show in the notification panel.
		notification.setLatestEventInfo(this, contentTitle, contentText,
				contentIntent);

		// Send the notification.
		mNotificationManager.notify(1, notification);

	}


		



	/****************************************************************/
	/* Methods to implement the MqttCallback interface */
	/****************************************************************/
	private class MessageHandler implements MqttCallback {
		/**
		 * @see MqttCallback#connectionLost(Throwable)
		 */
		public void connectionLost(Throwable cause) {
			// Called when the connection to the server has been lost.
			// An application may choose to implement reconnection
			// logic at this point.
			// This sample simply exits.
			Log.d("MQTT", "Connection to " + broker + " lost!" + cause);
			client = null;
			Thread t = new Thread(new Runnable() {

				public void run() {
					do {// pause for 5 seconds and try again;
						Log.d("MQTT",
								"sleeping for 10 seconds before trying to reconnect");
						try {
							Thread.sleep(10 * 1000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					} while (!connect2MB());
					Log.d("MQTT", "reconnected");
				}
			});
		}

		/**
		 * @see MqttCallback#deliveryComplete(MqttDeliveryToken)
		 */
		public void deliveryComplete(MqttDeliveryToken token) {
			// Called when a message has completed delivery to the
			// server. The token passed in here is the same one
			// that was returned in the original call to publish.
			// This allows applications to perform asychronous
			// delivery without blocking until delivery completes.

			// This sample demonstrates synchronous delivery, by
			// using the token.waitForCompletion() call in the main thread.
		}

		/**
		 * @see MqttCallback#messageArrived(MqttTopic, MqttMessage)
		 */
		public void messageArrived(MqttTopic topic, MqttMessage message)
				throws MqttException {
			// Called when a message arrives from the server.

			String time = new Timestamp(System.currentTimeMillis()).toString();

			Log.d("MQTT", "Time:\t" + time + "  Topic:\t" + topic.getName()
					+ "  Message:\t" + new String(message.getPayload())
					+ "  QoS:\t" + message.getQos());

			String msg = new String(message.getPayload());
			
			if (messages.size() >= 5)
			{
				messages.remove(0);				
			}
			messages.add(msg);	
			
			StringBuilder csvList = new StringBuilder();
			for(String s : messages){
			      csvList.append(s);
			      csvList.append("¤");
			      Log.d("MQTT",s);
			}
			editor.putString("myList", csvList.toString());
			editor.commit();
			
			runOnUiThread(new Runnable() {
				public void run() {
					adapter.notifyDataSetChanged();

				}
			});

			Log.d("MQTT", msg);

			showNotification(topic.getName(), new String(message.getPayload()));

		}

		/****************************************************************/
		/* End of MqttCallback methods */
		/****************************************************************/

	}

}
